/*
 ------------------------------------------------------------------------------
 Copyright (C) 2013 Eternal Games.

 This file is part of the GLQuake source code.

 The GLQuake source code is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or (at your
 option) any later version.

 The GLQuake source code is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 more details.

 You should have received a copy of the GNU General Public License along with
 the GLQuake source code; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ------------------------------------------------------------------------------
*/


//
// cg_draw.cpp - 2D drawing
//

// TODO:
// - status bar / inventory will be moved to into a GUI later on


#include "cg_local.h"


/*
 ==================
 
 Updates the lagometer's frame interpolate / extrapolate graph
 ==================
*/
void CG_UpdateFrameGraph (int timeDelta){

}

/*
 ==================
 
 Updates the lagometer's snapshot latency / drop graph
 ==================
*/
void CG_UpdateSnapshotGraph (int ping, bool rateDelayed){

}


/*
 ==============================================================================

 STATUS BAR & INVENTORY

 ==============================================================================
*/

#define SBAR_CHAR_WIDTH				24
#define SBAR_CHAR_HEIGHT			24

#define SBAR_MINUS_FRAME			10

#define	SBAR_BAR_X					((SCREEN_WIDTH * 0.5f) - (SBAR_BAR_W / 2))
#define	SBAR_BAR_Y					((SCREEN_HEIGHT) - (SBAR_BAR_H))
#define	SBAR_BAR_W					320
#define	SBAR_BAR_H					24

#define	SBAR_ARMOR_X				((SCREEN_WIDTH * 0.5f) - (SBAR_BAR_W / 2))
#define	SBAR_ARMOR_Y				((SCREEN_HEIGHT) - (SBAR_ARMOR_H))
#define	SBAR_ARMOR_W				24
#define	SBAR_ARMOR_H				24

#define	SBAR_FACE_X					((SCREEN_WIDTH * 0.5f) - (SBAR_BAR_W / 2) + (112))		// FIXME: 112 should be calculation
#define	SBAR_FACE_Y					((SCREEN_HEIGHT) - (SBAR_FACE_W))
#define	SBAR_FACE_W					24
#define	SBAR_FACE_H					24

#define SBAR_HEALTH_COUNT_X			((SCREEN_WIDTH * 0.5f) - (SBAR_BAR_W / 2) + (112))		// FIXME: 112 should be calculation
#define SBAR_HEALTH_COUNT_Y			(SCREEN_HEIGHT) - (SBAR_BAR_H)

#define	SBAR_AMMO_X					((SCREEN_WIDTH * 0.5f) - (SBAR_BAR_W / 2) + (224))		// FIXME: 224 should be calculation
#define	SBAR_AMMO_Y					((SCREEN_HEIGHT) - (SBAR_ARMOR_W))
#define	SBAR_AMMO_W					24
#define	SBAR_AMMO_H					24

#define SBAR_AMMO_COUNT_X			((SCREEN_WIDTH * 0.5f) - (SBAR_BAR_W / 2) + (222))
#define SBAR_AMMO_COUNT_Y			(SCREEN_HEIGHT) - (SBAR_BAR_H)

#define	SBAR_INVENTORY_X			((SCREEN_WIDTH * 0.5f) - (SBAR_INVENTORY_W / 2))
#define	SBAR_INVENTORY_Y			((SCREEN_HEIGHT) - (SBAR_INVENTORY_H + SBAR_BAR_H))
#define	SBAR_INVENTORY_W			320
#define	SBAR_INVENTORY_H			24


/*
 ==================
 CG_DrawNumber
 ==================
*/
static void CG_DrawNumber (float x, float y, int color, int width, int value){

	char	number[16], *ptr;
	int		len, frame;

	if (width < 1)
		return;

	// Clamp length
	if (width > 5)
		width = 5;

	Str_SPrintf(number, sizeof(number), "%i", value);
	len = Str_Length(number);
	if (len > width)
		len = width;

	// Draw it
	x += 2 + SBAR_CHAR_WIDTH + (width - len);
	ptr = number;
	while (*ptr && len){
		if (*ptr == '-')
			frame = SBAR_MINUS_FRAME;
		else
			frame = *ptr - '0';

		glqRenderer->DrawStretchPic(x, y, SBAR_CHAR_WIDTH, SBAR_CHAR_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, H_ALIGN_CENTER, 1.0f, V_ALIGN_BOTTOM, 1.0f, cgs.sbNumberMaterials[color][frame]);

		x += SBAR_CHAR_WIDTH;
		ptr++;
		len--;
	}
}

/*
 ==================
 CG_DrawStatusBar
 ==================
*/
static void CG_DrawStatusBar (){

	glqRenderer->SetColor(colorWhite);
	glqRenderer->DrawStretchPic(SBAR_BAR_X, SBAR_BAR_Y, SBAR_BAR_W, SBAR_BAR_H, 0.0f, 0.0f, 1.0f, 1.0f, H_ALIGN_CENTER, 1.0f, V_ALIGN_BOTTOM, 1.0f, cgs.sbBarMaterial);
}

/*
 ==================
 CG_DrawArmor
 ==================
*/
static void CG_DrawArmor (){

	// TODO: set the right armor icon

	glqRenderer->SetColor(colorWhite);
	glqRenderer->DrawStretchPic(SBAR_ARMOR_X, SBAR_ARMOR_Y, SBAR_ARMOR_W, SBAR_ARMOR_H, 0.0f, 0.0f, 1.0f, 1.0f, H_ALIGN_CENTER, 1.0f, V_ALIGN_BOTTOM, 1.0f, cgs.sbArmorMaterials[0]);
}

/*
 ==================
 CG_DrawFace
 ==================
*/
static void CG_DrawFace (){

	// TODO: set the right face animation frame

	glqRenderer->SetColor(colorWhite);
	glqRenderer->DrawStretchPic(SBAR_FACE_X, SBAR_FACE_Y, SBAR_FACE_W, SBAR_FACE_H, 0.0f, 0.0f, 1.0f, 1.0f, H_ALIGN_CENTER, 1.0f, V_ALIGN_BOTTOM, 1.0f, cgs.sbFaceInvulnerableMaterials[0]);
}

/*
 ==================
 CG_DrawHealth
 ==================
*/
static void CG_DrawHealth (){

	// TODO: set the right health count

	CG_DrawNumber(SBAR_HEALTH_COUNT_X, SBAR_HEALTH_COUNT_Y, 0, 3, 100);
}

/*
 ==================
 CG_DrawAmmo
 ==================
*/
static void CG_DrawAmmo (){

	// TODO: set the right ammo icon and count

	glqRenderer->SetColor(colorWhite);
	glqRenderer->DrawStretchPic(SBAR_AMMO_X, SBAR_AMMO_Y, SBAR_AMMO_W, SBAR_AMMO_H, 0.0f, 0.0f, 1.0f, 1.0f, H_ALIGN_CENTER, 1.0f, V_ALIGN_BOTTOM, 1.0f, cgs.sbAmmoMaterials[0]);

	CG_DrawNumber(SBAR_AMMO_COUNT_X, SBAR_AMMO_COUNT_Y, 0, 3, 200);
}

/*
 ==================
 CG_DrawInventory
 ==================
*/
static void CG_DrawInventory (){

	glqRenderer->SetColor(colorWhite);
	glqRenderer->DrawStretchPic(SBAR_INVENTORY_X, SBAR_INVENTORY_Y, SBAR_INVENTORY_W, SBAR_INVENTORY_H, 0.0f, 0.0f, 1.0f, 1.0f, H_ALIGN_CENTER, 1.0f, V_ALIGN_BOTTOM, 1.0f, cgs.sbItemBarMaterial);
}

/*
 ==================
 
 ==================
*/
static void CG_DrawWeapons (){

}

/*
 ==================
 
 ==================
*/
static void CG_DrawAmmoCount (){

}

/*
 ==================
 
 ==================
*/
static void CG_DrawItem (){

}

/*
 ==================
 
 ==================
*/
static void CG_DrawSigil (){

}

/*
 ==================
 CG_DrawHUD
 ==================
*/
static void CG_DrawHUD (){

	if (!cg_drawHUD->integerValue)
		return;

	CG_DrawStatusBar();
	CG_DrawArmor();
	CG_DrawFace();
	CG_DrawHealth();
	CG_DrawAmmo();
	CG_DrawInventory();
	CG_DrawWeapons();
	CG_DrawAmmoCount();
	CG_DrawItem();
	CG_DrawSigil();
}


// ============================================================================


/*
 ==================
 CG_DrawCrosshair
 ==================
*/
static void CG_DrawCrosshair (){

	int				crosshair;
	float			x, y, w, h;
	glqVec4			color;

	if (!cg_drawCrosshair->integerValue)
		return;

	// Select crosshair
	crosshair = (cg_crosshair->integerValue - 1) % NUM_CROSSHAIRS;
	if (crosshair < 0)
		return;

	// Set dimensions and position
	w = cg_crosshairSize->integerValue;
	h = cg_crosshairSize->integerValue;

	x = cg_crosshairX->integerValue + ((SCREEN_WIDTH - w) * 0.5f);
	y = cg_crosshairY->integerValue + ((SCREEN_HEIGHT - h) * 0.5f);

	// Set color and alpha
	if (cg_crosshairHealth->integerValue){

		// TODO: finish this when playerState is done

	}
	else {
		color[0] = color_table[cg_crosshairColor->integerValue & COLOR_MASK][0];
		color[1] = color_table[cg_crosshairColor->integerValue & COLOR_MASK][1];
		color[2] = color_table[cg_crosshairColor->integerValue & COLOR_MASK][2];
		color[3] = 1.0f * glqMath::ClampFloat(cg_crosshairAlpha->floatValue, 0.0f, 1.0f);
	}

	// Draw it
	glqRenderer->SetColor(color);
	glqRenderer->DrawStretchPic(x, y, w, h, 0.0f, 0.0f, 1.0f, 1.0f, H_ALIGN_CENTER, 1.0f, V_ALIGN_CENTER, 1.0f, cgs.crosshairMaterials[crosshair]);
}

/*
 ==================
 
 ==================
*/
static void CG_DrawCenterString (){

}

/*
 ==================
 
 ==================
*/
static void CG_DrawPause (){

}

/*
 ==================
 CG_Draw2D
 ==================
*/
void CG_Draw2D (){

	if (!cg_draw2D->integerValue)
		return;

	// Update the test post-process material
	CG_UpdateTestPostProcess();

	// Draw the crosshair
	CG_DrawCrosshair();

	// Draw the center string
	CG_DrawCenterString();

	// Draw the HUD interface
	CG_DrawHUD();

	// Draw the pause
	CG_DrawPause();
}